package stone;

import java.util.HashMap;

public class Symbols {
	
	public static class Location {
		public int nest, index;
		
		public Location(int nest, int index) {
			this.nest = nest;
			this.index = index;
		}
	}
	
	protected Symbols outer;
	protected HashMap<String, Integer> table;
	
	public Symbols() {
		this(null);
	}
	
	public Symbols(Symbols outer) {
		this.outer = outer;
		this.table = new HashMap<String, Integer>();
	}
	
	public int size() {
		return table.size();
	}
	
	public void append(Symbols s) {
		table.putAll(s.table);
	}
	
	public Integer find(String key) {
		// 查询变量，以变量名作为key
		// 实际操作是从字典中查询变量
		return table.get(key);
	}
	
	public Location get(String key) {
		return get(key, 0);
	}
	
	public Location get(String key, int nest) {
		// 递归查询变量，以变量名为key，并通过嵌套层数nest来确保递归查询
		// 如果找到，返回Location
		// 如果没有找到，返回null
		Integer index = table.get(key);
		if (index == null) {
			if (outer == null) {
				return null;
			}
			else {
				return outer.get(key, nest+1);
			}
		}
		else {
			return new Location(nest,  index.intValue());
		}
	}
	
	public int putNew(String key) {
		// 存入变量，以变量名作为key
		// 查询(非递归查询)是否存在这个变量，如果存在，直接返回其下标
		// 如果不存在，将(变量名, 变量)存入table，并且返回其下标
		Integer i = find(key);
		if (i == null) {
			return add(key);
		}
		else {
			return i;
		}
	}
	
	public Location put(String key) {
		// 存入变量，以变量名为key
		// 首先(递归)查询是否存在这个变量，如果存在，直接返回其Location
		// 如果不存在，则在当前层添加这个变量，并且返回Location
		Location loc = get(key, 0);
		if (loc == null) {
			return new Location(0, add(key));
		}
		else {
			return loc;
		}
	}
	
	protected int add(String key) {
		// 添加新的变量名，以变量名作为key，存入(key, index), 并将index返回
		int i = table.size();
		table.put(key, i);
		return i;
	}

}
